#include "XThreadPool.h"
#include "XThread.h"
#include <iostream>
#include <XTools.h>
#ifdef _WIN32
#include <Windows.h>
#else
#include <signal.h>
#endif
// 用于线程退出判断
static bool is_exit_all = false;
// 线程列表
static std::vector<std::shared_ptr<XThread>> all_threads;
static std::mutex all_threads_mutex;
void XThreadPool::ExitAllThread()
{
    is_exit_all = true;
    all_threads_mutex.lock();
    for (auto &thread : all_threads)
    {
        thread->exit();
    }
    all_threads_mutex.unlock();
    std::this_thread::yield();
}

void XThreadPool::Wait()
{
    while (!is_exit_all)
    {
        // std::this_thread::yield();
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

class CXThreadPool : public XThreadPool
{
public:
    CXThreadPool();
    virtual void dispatch(XTask *task) override;
    virtual void init(int threadCount) override;
    virtual ~CXThreadPool();

private:
    // 线程数量
    int thread_count_ = 0;
    // 上次分配任务的线程
    int last_thread_ = -1;
    std::vector<std::shared_ptr<XThread>> threads_;
};

CXThreadPool::CXThreadPool()
{

}

void CXThreadPool::init(int threadCount)
{
    thread_count_ = threadCount;
    last_thread_ = -1;
    for (int i = 0; i < thread_count_; i++)
    {
        threads_.push_back(std::make_shared<XThread>());
        threads_[i]->setId(i + 1);
        threads_[i]->start();
        all_threads_mutex.lock();
        all_threads.push_back(threads_[i]);
        all_threads_mutex.unlock();
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
}

CXThreadPool::~CXThreadPool()
{
}

/**
 * @brief 分配任务到线程池中的线程
 *
 * 本函数负责将任务分配给线程池中的线程执行。它首先检查任务是否为空，
 * 如果不为空，则根据轮询策略选择下一个线程，并将任务添加到该线程的任务队列中。
 *
 * @param task 要分配的任务，类型为XTask*
 */
void CXThreadPool::dispatch(XTask *task)
{
    if (task == nullptr)
    {
        std::cout << "task is nullptr" << std::endl;
        return;
    }
    last_thread_ = (last_thread_ + 1) % thread_count_;
    auto thread = all_threads[last_thread_];
    // 添加任务
    thread->addTask(task);
    // 激活线程
    thread->activate();
}

XThreadPool *XThreadPoolFactory::Create()
{
    // socket 线程池
    static std::mutex mutex;
    static bool is_init = false;
    mutex.lock();
    if (!is_init)
    {
#ifdef _WIN32
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
            XCOM_LOG_ERROR("WSAStartup failed");
            return nullptr;
        }
#else
        if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
        {
            XCOM_LOG_ERROR("signal failed");
            return nullptr;
        }
#endif
        is_init = true;
    }
    mutex.unlock();
    return new CXThreadPool();
}
